﻿using System;
using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Factories;
using FarseerGames.GettingStarted.ScreenSystem;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Net;
using Netpong.Networking;
using NetPong.Networking;
using XNALibrary;
using Microsoft.Xna.Framework.Input;

namespace NetPong
{
    public abstract class Ball : ITransmittable, IRenderable
    {
        public Body body;
        public int ObjectId { get { return objectId; } }
        private int objectId = 0;

        CurrentRenderMethod currentRenderMethod;
       
        protected Vector2 ballOrigin;
        protected Geom geom;
        protected int radius;
        InputHandler input;
        Vector2 initPos;

        public Ball()
        { }

        public Ball(NetworkManager nm,Vector2 position, int radius, PhysicsSimulator physicsSimulator)
        {
            //objectId = nm.CreateNetworkObj(this);
            body = BodyFactory.Instance.CreateCircleBody(physicsSimulator, radius, .5f);
            body.Position = position;
            initPos = position;

            this.radius = radius;

            this.geom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator, body, radius, 20);

            currentRenderMethod = RenderDefault;
            //currentRenderMethod = RenderAnimation;
        }

        public Ball(NetworkManager nm, Vector2 position, int radius, PhysicsSimulator physicsSimulator, InputHandler ih)
            : this(nm, position, radius, physicsSimulator)
        {
            input = ih;
        }

        public virtual void Update()
        {
            if (input != null)
            {
                KeyboardHandler kbh = input.KeyboardHandler;

                if (kbh.IsKeyDown(Keys.Left))
                {
                    body.ApplyForce(new Vector2(200, 0));
                }
                if (kbh.IsKeyDown(Keys.Right))
                {
                    body.ApplyForce(new Vector2(-200, 0));
                }
                if (kbh.IsKeyDown(Keys.Up))
                {
                    body.ApplyForce(new Vector2(0, 200));
                }
                if (kbh.IsKeyDown(Keys.Down))
                {
                    body.ApplyForce(new Vector2(0, -200));
                }
                if(kbh.IsKeyDown(Keys.Space))
                {
                    body.ClearForce();
                    body.LinearVelocity = new Vector2(0, 0);
                    Console.WriteLine("Ball position: " + body.Position);
                }
                if(kbh.IsKeyDown(Keys.Back))
                {
                    body.Position = initPos;
                }
            }
        }

        #region ITransmittable Members
        public void UpdateFromNetwork(PacketReader packetReader)
        {
            body.Position = packetReader.ReadVector2();
            body.Rotation = packetReader.ReadSingle();
        }

        public PacketWriter WriteToNetwork()
        {
            PacketWriter packetWriter = new PacketWriter();
            packetWriter.Write(objectId);
            packetWriter.Write(body.Position);
            packetWriter.Write(body.Rotation);

            return packetWriter;
        }
        #endregion

        #region IRenderable Members
        public void Render(RenderControl rc, GameTime gt)
        {
            currentRenderMethod(rc, gt);
        }

        public abstract void RenderDefault(RenderControl rc, GameTime gt);

        public abstract void RenderAnimation(RenderControl rc, GameTime gt);

        #endregion
    }
}

